﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace VisualStudioScreenSaver
{
    public partial class Form1 : Form
    {
        // Initialize variables
        Point MouseXY;
        int speedX = 5000;
        bool rUp, gUp, bUp;
        byte r1, g1, b1, r2, g2, b2, rn, gn, bn;
        int i;

        public Form1()
        {
            InitializeComponent();

            // Hide the cursor (screensaver)
            Cursor.Hide();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Set standard LayOut
            vsPicture.Location = new Point((this.Width - vsPicture.Width)/2, (this.Height - vsPicture.Height)/2);
            this.BackColor = Color.FromArgb(255, 104, 33, 122);
            
            i = 0;

            // Give new color rgb and start fade
            r2 = 170;
            g2 = 0;
            b2 = 255;
            ColorFade();
        }

        void ColorFade()
        {
            // if number two from the list done (first time from Form1_Load()), set i to 0
            if (i == 16)
                i = 0;
            
            // Increase i
            i++;

            // Set original rgb to BackColor of the form
            r1 = this.BackColor.R;
            g1 = this.BackColor.G;
            b1 = this.BackColor.B;

            // Initialisation of differences set in next #region
            byte rD;
            byte gD;
            byte bD;

            // Check wich is greater and get the difference between old and new + set to count up or down
            #region if D & Up
            if (r1 > r2)
            {
                rD = (byte)((int)r1 - (int)r2);
                rUp = false;
            }
            else
            {
                if (r1 != r2)
                {
                    rD = (byte)((int)r2 - (int)r1);
                    rUp = true;
                }
                else
                    rD = 1;
            }

            if (g1 > g2)
            {
                gD = (byte)((int)g1 - (int)g2);
                gUp = false;
            }
            else
            {
                if (g1 != g2)
                {
                    gD = (byte)((int)g2 - (int)g1);
                    gUp = true;
                }
                else
                    gD = 1;
            }

            if (b1 > b2)
            {
                bD = (byte)((int)b1 - (int)b2);
                bUp = false;
            }
            else
            {
                if (b1 != b2)
                {
                    bD = (byte)((int)b2 - (int)b1);
                    bUp = true;
                }
                else
                    bD = 1;
            }
            #endregion

            // Interval time for Timer is total time / steps of increasement (difference between old and new)
            RTimer.Interval = (int)(speedX / rD);
            GTimer.Interval = (int)(speedX / gD);
            BTimer.Interval = (int)(speedX / bD);

            // set new rgb to the old ones
            rn = r1;
            gn = g1;
            bn = b1;

            // enable timers
            RTimer.Enabled = true;
            GTimer.Enabled = true;
            BTimer.Enabled = true;
        }

        #region Tickers
        private void RTimer_Tick(object sender, EventArgs e)
        {
            // If new rgb is the rgb we want, disable timer and go to next fade
            if (rn != r2)
            {
                // increase (or decrease) new rgb
                if (rUp)
                    rn = (byte)(rn + 1);
                else
                    rn = (byte)(rn - 1);

                // set rgb as background
                MakeBackground();
            }
            else
            {
                RTimer.Enabled = false;
                NextOne(i);
            }
        }

        // Same thing as above
        private void GTimer_Tick(object sender, EventArgs e)
        {
            if (gn != g2)
            {
                if (gUp)
                    gn = (byte)(gn + 1);
                else
                    gn = (byte)(gn - 1);

                MakeBackground();
            }
            else
            {
                GTimer.Enabled = false;
                NextOne(i);
            }
        }

        // Same thing as above
        private void BTimer_Tick(object sender, EventArgs e)
        {
            if (bn != b2)
            {
                if (bUp)
                    bn = (byte)(bn + 1);
                else
                    bn = (byte)(bn - 1);

                MakeBackground();
            }
            else
            {
                BTimer.Enabled = false;
                NextOne(i);
            }
        }
        #endregion

        // Set the background to the new rgb
        private void MakeBackground()
        {
            this.BackColor = Color.FromArgb(255, rn, gn, bn);
        }

        // Set the next fade
        private void NextOne(int i)
        {
            // Only set the next if the previous one is done (need this because the timers don't end exactly at the same time)
            if (this.BackColor.R == r2 && this.BackColor.G == g2 && this.BackColor.B == b2)
            {
                // Get the value of i and set new fade
                switch (i)
                {
                    // first time come here
                    case 1:
                        // set new rgb and start fade
                        r2 = 244;
                        g2 = 115;
                        b2 = 208;
                        ColorFade();
                        break;

                    #region case 2 - 16
                    // second time come here (same as above)
                    case 2:
                        r2 = 217;
                        g2 = 0;
                        b2 = 115;
                        ColorFade();
                        break;

                    // third time here
                    case 3:
                        r2 = 162;
                        g2 = 0;
                        b2 = 37;
                        ColorFade();
                        break;

                    // fourth time here
                    case 4:
                        r2 = 229;
                        g2 = 20;
                        b2 = 0;
                        ColorFade();
                        break;

                    // fifth time here
                    case 5:
                        r2 = 250;
                        g2 = 105;
                        b2 = 0;
                        ColorFade();
                        break;

                    case 6:
                        r2 = 241;
                        g2 = 163;
                        b2 = 11;
                        ColorFade();
                        break;

                    case 7:
                        r2 = 227;
                        g2 = 200;
                        b2 = 0;
                        ColorFade();
                        break;

                    case 8:
                        r2 = 164;
                        g2 = 197;
                        b2 = 0;
                        ColorFade();
                        break;

                    case 9:
                        r2 = 96;
                        g2 = 170;
                        b2 = 23;
                        ColorFade();
                        break;

                    case 10:
                        r2 = 0;
                        g2 = 138;
                        b2 = 3;
                        ColorFade();
                        break;

                    case 11:
                        r2 = 1;
                        g2 = 171;
                        b2 = 170;
                        ColorFade();
                        break;

                    case 12:
                        r2 = 27;
                        g2 = 160;
                        b2 = 225;
                        ColorFade();
                        break;

                    case 13:
                        r2 = 0;
                        g2 = 80;
                        b2 = 239;
                        ColorFade();
                        break;

                    case 14:
                        r2 = 106;
                        g2 = 0;
                        b2 = 255;
                        ColorFade();
                        break;

                    case 15:
                        r2 = 104;
                        g2 = 33;
                        b2 = 122;
                        ColorFade();
                        break;

                    case 16:
                        r2 = 170;
                        g2 = 0;
                        b2 = 255;
                        ColorFade();
                        break;
                    #endregion
                }
            }
        }

        #region Exit
        // Exit by mouseclick
        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            Close();
        }

        // Exit by key event
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            Close();
        }

        // Exit by mousemovement
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (!MouseXY.IsEmpty)
            {
                if (MouseXY != new Point(e.X, e.Y))
                    Close();
            }

            MouseXY = new Point(e.X, e.Y);
        }
        #endregion
    }
}
